#ifndef POINT_PATH_HPP
#define POINT_PATH_HPP

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <vector>

#include <SFML/System/Vector2.hpp>

#include <SmegTools/Config.h>
#include <SmegTools/Debug/DebugNew.hpp>

#ifdef _DEBUG
namespace sf {
    class RenderWindow;
}
#endif

namespace smeg {
    namespace ai {
        
////////////////////////////////////////////////////////////
/// Manage the steering functions called by the entity
////////////////////////////////////////////////////////////
class PointPath
{
public:
    enum eLoopType {
        eNoLoop         = 0,
        eLoop           = 1,
        eBackAndForth   = 2,
        eMAX_LOOP_TYPE
    };

    ////////////////////////////////////////////////////////////
    /// Default Constructor
    ///
    ////////////////////////////////////////////////////////////
                                    PointPath();
    ////////////////////////////////////////////////////////////
    /// Constructor with a base path
    ///
    ////////////////////////////////////////////////////////////
                                    PointPath( const std::vector< sf::Vector2f> _BasePath, eLoopType _eLoop = eNoLoop, bool _bIsReverse = false );
    ////////////////////////////////////////////////////////////
    /// Copy Constructor
    ///
    /// \param _Copy :      Manager to copy
    ///
    ////////////////////////////////////////////////////////////
                                    PointPath( const PointPath& _Copy );
    ////////////////////////////////////////////////////////////
    /// Destructor
    ///
    ////////////////////////////////////////////////////////////
                                    ~PointPath();

    ////////////////////////////////////////////////////////////
    /// Add a waypoint to the end
    ///
    ////////////////////////////////////////////////////////////
    void                            Setup( const std::vector< sf::Vector2f> _BasePath, eLoopType _eLoop = eNoLoop, bool _bIsReverse = false );

    ////////////////////////////////////////////////////////////
    /// Operator=
    ///
    ////////////////////////////////////////////////////////////
    PointPath&                      operator=( const PointPath& _Copy );

    ////////////////////////////////////////////////////////////
    /// Add a waypoint to the end
    ///
    ////////////////////////////////////////////////////////////
    void                            AddWaypoint( const sf::Vector2f _Waypoint );

    ////////////////////////////////////////////////////////////
    /// Start to the current waypoint
    ///
    ////////////////////////////////////////////////////////////
    void                            Start();

    ////////////////////////////////////////////////////////////
    /// Set path to loop
    ///
    ////////////////////////////////////////////////////////////
    void                            SetLoopType( eLoopType _eLoop );

    ////////////////////////////////////////////////////////////
    /// Set path to reverse
    ///
    ////////////////////////////////////////////////////////////
    void                            Reverse( bool _bReverse );
    void                            ReverseOn();
    void                            ReverseOff();

    ////////////////////////////////////////////////////////////
    /// Is the path finished ?
    ///
    ////////////////////////////////////////////////////////////
    bool                            IsFinished() const;
    
    ////////////////////////////////////////////////////////////
    /// Get current waypoint
    ///
    ////////////////////////////////////////////////////////////
    const sf::Vector2f&             GetCurrentWaypoint() const;

    ////////////////////////////////////////////////////////////
    /// Go to the next waypoint
    ///
    ////////////////////////////////////////////////////////////
    void                            SetNextWaypoint();

private:
    ////////////////////////////////////////////////////////////
    /// Loop the path
    ///
    ////////////////////////////////////////////////////////////
    void                            Loop();

    std::vector< sf::Vector2f >     m_Waypoints;
    std::vector< sf::Vector2f >::iterator m_CurrentWaypoint;
    
    eLoopType                       m_eLoopType;
    bool                            m_bIsReverse;

#ifdef _DEBUG
public:
    void                            DebugRender( sf::RenderWindow* _pRenderWindow ) const;
#endif // _DEBUG

};

/************************** Inline ************************/
inline void PointPath::SetLoopType( eLoopType _eLoop ) {
    m_eLoopType = _eLoop;
}

inline bool PointPath::IsFinished() const {
    return (m_bIsReverse ? m_CurrentWaypoint == m_Waypoints.begin() : m_CurrentWaypoint == m_Waypoints.end() - 1);
}

inline const sf::Vector2f& PointPath::GetCurrentWaypoint() const {
    return *m_CurrentWaypoint;
}

inline void PointPath::Reverse( bool _bReverse ) {
    m_bIsReverse = _bReverse;
}

inline void PointPath::ReverseOn() {
    Reverse( true );
}

inline void PointPath::ReverseOff() {
    Reverse( false );
}


    } // namespace ai
} // namespace smeg

#include <SmegTools/Debug/DebugNewOff.hpp>

#endif // POINT_PATH_HPP
